<template>
  <div v-if="proxy.isAuth(['ROOT', 'APPOINTMENT:SELECT'])">
    <el-form :inline="true" :model="dataForm" :rules="dataRule" ref="form">
      <el-form-item>
        <el-date-picker
            v-model="dataForm.date"
            type="date"
            placeholder="选择日期"
            :editable="false"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            :clearable="false"
        />
      </el-form-item>

      <el-form-item prop="name">
        <el-input
            v-model="dataForm.name"
            placeholder="姓名"
            maxlength="10"
            class="input"
            clearable
        />
      </el-form-item>

      <el-form-item prop="tel">
        <el-input
            v-model="dataForm.tel"
            placeholder="电话号码"
            maxlength="11"
            class="input"
            clearable
        />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="searchHandle()">查询</el-button>
        <el-button type="success" @click="checkinHandle()">体检签到</el-button>
        <el-button type="danger" @click="finishHandle()">完成体检</el-button>
      </el-form-item>

      <el-form-item class="mold">
        <el-radio-group v-model="dataForm.statuslabel" @change="searchHandle">
          <el-radio-button label="全部"></el-radio-button>
          <el-radio-button label="未签到"></el-radio-button>
          <el-radio-button label="已签到"></el-radio-button>
          <el-radio-button label="已结束"></el-radio-button>
          <el-radio-button label="已关闭"></el-radio-button>
        </el-radio-group>
      </el-form-item>

    </el-form>
    <el-table :data="data.datalist"
              :header-cell-style="{'background': '#f5f7fa'}"
              :border="true"
              :loading="data.loading"
              @selection-change="selectionChangeHandle">

      <el-table-column type="selection"
                       :selectable="selectable"
                       align="center"
                       width="50"
                       fixed/>

      <el-table-column type="index"
                       header-align="center"
                       align="center"
                       width="120"
                       label="字号"
                       fixed>
        <template #default="scope">
          <span>{{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }}</span>
        </template>
      </el-table-column>

      <el-table-column prop="name"
                       header-align="center"
                       align="center"
                       label="姓名"
                       width="200"
                       fixed/>

      <el-table-column prop="sex"
                       header-align="center"
                       align="center"
                       label="性别"
                       width="100"/>

      <el-table-column prop="age"
                       header-align="center"
                       align="center"
                       label="年龄"
                       width="100"/>

      <el-table-column prop="tel"
                       header-align="center"
                       align="center"
                       label="联系电话"
                       width="150"/>

      <el-table-column prop="pid"
                       header-align="center"
                       align="center"
                       label="身份证号"
                       width="190"/>
      <el-table-column prop="company"
                       header-align="center"
                       align="center"
                       label="公司名称"
                       width="200"/>

      <el-table-column prop="title"
                       header-align="center"
                       align="center"
                       label="体检套餐"
                       min-width="200"/>

      <el-table-column prop="status"
                       header-align="center"
                       align="center"
                       label="状态"
                       width="120"/>

      <el-table-column fixed="right"
                       header-align="center"
                       align="center"
                       width="150"
                       label="操作">
        <template #default="scope">
          <el-button type="text"
                     :disabled="!proxy.isAuth(['ROOT', 'APPOINTMENT:SELECT'])"
                     @click="guidanceHandle(scope.row.id)">
            引导单
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
        @size-change="sizeChangeHandle"
        @current-change="currentChangeHandle"
        :current-page="data.pageIndex"
        :page-size="data.pageSize"
        :page-sizes="[10, 20, 50]"
        :total="data.totalCount"
        layout="total, sizes, prev, pager, next, jumper">
    </el-pagination>
    <el-dialog title="体检签到" v-if="proxy.isAuth(['ROOT', 'APPOINTMENT:UPDATE'])"
               :close-on-click-modal="false"
               v-model="checkinDialog.visible"
               width="500px"
               :before-close="closeHandle">
      <div class="card-info">
        <div class="left">
          <el-form :model="checkinDialog.dataForm" ref="dialogform" label-width="60px">
            <el-form-item label="姓名">
              <el-input v-model="checkinDialog.dataForm.name" disabled/>
            </el-form-item>
            <el-form-item label="性别">
              <el-input v-model="checkinDialog.dataForm.sex" disabled/>
            </el-form-item>
            <el-form-item label="身份证">
              <el-input v-model="checkinDialog.dataForm.pid" disabled/>
            </el-form-item>
          </el-form>
        </div>
        <div class="right">
          <img :src="checkinDialog.dataForm.photo1" class="photo" v-if="checkinDialog.dataForm.photo_1 !== null"/>
          <div class="empty" v-if="checkinDialog.dataForm.photo_1 === null">
            <el-icon :size="60" class="icon">
              <Avatar/>
            </el-icon>
          </div>
        </div>
      </div>
      <div class="photo-container">
        <div class="empty" v-show="checkinDialog.showEmpty">
          <SvgIcon name="camera" class="camera"/>
          <ol>
            <li>先刷体检人身份证，验证通过后会自动启动摄像头。</li>
            <li>必须要注意拍摄照片中只能有唯一的人脸面部信息，如果存在多张人脸则会报错。</li>
            <li>务必拍摄体检人正脸照片，不可以佩戴墨镜或者遮挡面部的配饰。</li>
          </ol>
        </div>
        <video id="video" autoplay v-show="checkinDialog.showVideo"></video>
        <canvas id="photo" width="460" height="345" v-show="checkinDialog.showPhoto"></canvas>
      </div>
      <template #footer>
    <span class="dialog-footer">
        <el-button type="primary"
                   :icon="checkinDialog.btnIcon"
                   :disabled="checkinDialog.showEmpty"
                   @click="takePhotoHandle">
            {{ checkinDialog.btnText }}
        </el-button>
        <el-button @click="closeHandle">取消</el-button>
        <el-button type="success"
                   :disabled="checkinDialog.dataForm.pid == null || checkinDialog.dataForm.photo_2 == null"
                   @click="dataFormSubmit">
            签到
        </el-button>
    </span>
      </template>
    </el-dialog>
    <el-dialog title="体检引导单"
               v-if="proxy.isAuth(['ROOT','APPOINTMENT:SELECT'])"
               v-model="guidanceDialog.visible" width="800px">
      <div class="guidance" id="pdfDom" :name="guidanceDialog.name">
        <h2 class="title">神州大健康体检项目导引单</h2>
        <div class="summary">
          <table class="base-info">
            <tbody> <!-- 添加 tbody 来包裹 tr -->
            <tr>
              <td class="label">姓名:</td>
              <td class="value">{{ guidanceDialog.name }}</td>
              <td class="label">性别:</td>
              <td class="value">{{ guidanceDialog.sex }}</td>
              <td class="label">年龄:</td>
              <td class="value">{{ guidanceDialog.age }}</td>
            </tr>
            </tbody>
          </table>

          <img class="qrcode" :src="guidanceDialog.qrCodeBase64"/>
        </div>

        <table class="checkup">
          <thead>
          <tr>
            <th>序号</th>
            <th align="left">检查地点</th> <!-- 修正了属性引号 -->
            <th align="left">检查项目</th> <!-- 修正了属性引号 -->
            <th>体检医生</th> <!-- 修正了 <th> 标签 -->
          </tr>
          </thead>
          <tbody>
          <tr v-for="(one, index) in guidanceDialog.checkup" :key="index">
            <td align="center">{{ index + 1 }}</td>
            <td>{{ one.place }}</td>
            <td>{{ one.name }}</td>
            <td>{{ one.doctor }}</td> <!-- 假设有一个 doctor 字段 -->
          </tr>
          </tbody>
        </table>
        <div class="desc">
          <p>请注意: 体检结束10天后，即可在神州大健康网站（http://www.szhis.com）查询到您的体检结果</p>
          <ul>
            <li>
              <el-icon>
                <PhoneFilled/>
              </el-icon>
              <span>体检咨询: 010-23891145</span>
            </li>
            <li>
              <el-icon>
                <PhoneFilled/>
              </el-icon>
              <span>体检咨询: 010-23891145</span>
            </li>
            <li>
              <el-icon>
                <PhoneFilled/>
              </el-icon>
              <span>体检咨询: 010-23891145</span>
            </li>
          </ul>
        </div>
      </div>
      <div class="operate">
        <el-button type="primary" size="large" :icon="Document" @click="getPdf()">下载导引单</el-button>
      </div>
    </el-dialog>
  </div>

</template>
<script setup lang="ts">
import {getCurrentInstance, reactive} from "vue";
import {dayjs, ElMessageBox, ElNotification} from "element-plus";
import {Camera} from "@element-plus/icons-vue";

const {proxy} = getCurrentInstance();
const dataForm = reactive({
  name: null,
  tel: null,
  date: dayjs().format('YYYY-MM-DD'),
  statusLabel: '全部',
  status: null
})
const dataRule = reactive({
  name: [
    {
      pattern: /^[\u4e00-\u9fa5]{1,10}$/,
      message: '姓名格式错误'
    }
  ],
  tel: [
    {
      pattern: /^1[1-9]\d{9}$/,
      message: '电话号码格式错误'
    }
  ]
});
const data = reactive({
  dataList: [],
  pageIndex: 1,
  pageSize: 10,
  totalCount: 0,
  loading: false,
  selections: []
})
const checkinDialog = reactive({
  visible: true,
  btnText: '拍照',
  btnIcon: Camera,
  showEmpty: true,
  showVideo: false,
  showPhoto: false,
  streamTrack: null,
  dataForm: {
    name: null,
    sex: null,
    pid: null,
    photo_1: null,
    photo_2: null
  }
})
const guidanceDialog = reactive({
  visible: true,
  name: null,
  sex: null,  // 修正了 'nu11' -> 'sex'
  age: null,
  pid: null,
  tel: null,
  date: null,
  company: null,
  qrCodeBase64: null,
  checkup: []
});

const webUrl = 'ws://127.0.0.1:30004/ws';
let ws = new WebSocket(webUrl);
ws.onopen = function (evt) {
  console.log('身份证读取WebSocket已连接');
};
ws.onclose = function (evt) {
  console.log('身份证读取WebSocket已经关闭');
}
ws.onmessage = function (messageEvent) {
  if (!checkinDialog.visible || !checkinDialog.showEmpty) {
    return;
  }

  // 把读卡内容转换成JSON对象
  const jsonObject = JSON.parse(messageEvent.data);

  // Ret属性0代表成功，其他代表读卡失败
  if (jsonObject.Ret === 0) {
    // Cmd是10001代表被动接收读卡结果，10000代表主动读取身份证内容
    if (jsonObject.Cmd === 10001) {
      // 获取UserParam信息
      const userParam = JSON.parse(window.atob(jsonObject.UserParam));

      // 姓名(结尾包含空格，字符串总长度为15个字符，必须要去除结尾空格)
      const name = hex2a(window.atob(userParam.CardInfo.Name)).trim();
      console.log(name);

      // 性别
      const sex = hex2a(window.atob(userParam.CardInfo.Sex)) === '1' ? '男' : '女';

      // 身份证号
      const pid = hex2a(window.atob(userParam.CardInfo.No));

      // 生日（例如19920315）
      const temp = hex2a(window.atob(userParam.CardInfo.Birthday)); // 转换生日格式
      const birthday = parseDateString(temp, '-', true); // 日期格式转换

      // 照片
      const image = 'data:image/jpg;base64,' + userParam.BmpInfo;
      // 起始有效期
      const validityPeriodBegin = hex2a(window.atob(userParam.CardInfo.ValidityPeriodBegin));
      const expiryBegin = parseDateString(validityPeriodBegin, '-', true);

      // 截止有效期
      const validityPeriodEnd = hex2a(window.atob(userParam.CardInfo.ValidityPeriodEnd));
      const expiryEnd = validityPeriodEnd !== '长期' ? parseDateString(validityPeriodEnd, '-', true) : '长期';
      if (expiryEnd !== '长期') {
        let valid = dayjs().isBetween(expiryBegin, expiryEnd); // 检查当前时间是否在有效期范围内

        if (!valid) {
          proxy.$message({
            message: "该体检人未预约", // 提示消息
            type: "error", // 错误类型
            duration: 1200 // 消息显示时间
          });
          return
        }
      }
      let json = {
        name: name,
        sex: sex,
        pid: pid
      }
      proxy.$http("/mis/appointment/hasAppointInToday", "POST", json, true, function (response) {
        let result = response.result;

        if (result == -1) {
          proxy.$message({
            message: '已经签到，无需重复签到',
            type: "warning",
            duration: 1200
          });
        } else if (result == 1) {
          // 在弹窗中显示身份证信息
          checkinDialog.dataForm.name = name;
          checkinDialog.dataForm.sex = sex;
          checkinDialog.dataForm.pid = pid;
          checkinDialog.dataForm.photo_1 = image;
          // 检查浏览器是否为 WebDriver 控制的浏览器
          let isWebDriver = navigator.webdriver;
          if (isWebDriver) {
            // WebDriver 控制的浏览器逻辑
            console.log("Browser is controlled by WebDriver.");
          }

          let bool = navigator.getUserMedia || navigator.webkitGetUserMedia;
          if (bool) {
            // 获取媒体流
            navigator.getUserMedia({audio: false, video: true}, function (stream) {
              // 根据ID查找视图层中的 video 控件
              let video = document.querySelector('#video');

              // 给视图层 video 控件设置数据流
              video.srcObject = stream;

              // 把视频流保存到模型层，将来关闭弹窗的时候可以切断视频流
              checkinDialog.streamTrack = stream.getTracks()[0];

              // 给视图层 video 控件成功加载视频流
              video.onloadedmetadata = function (e) {
                video.play(); // 播放视频流内容
                checkinDialog.showEmpty = false;
                checkinDialog.showPhoto = false;
                checkinDialog.showVideo = true
              }

              // 显示视频界面
              checkinDialog.showVideo = true;
            }, function (err) {
              proxy.$message({
                message: "开启摄像头失败",
                type: 'error',
                duration: 1200
              });
            });
          } else {
            proxy.$message({
              message: '当前电脑没有连接摄像头',
              type: 'error',
              duration: 1200
            });
          }
        } else {
          proxy.$message({
            message: '该体检人未预约',
            type: 'error',
            duration: 1200
          });
        }
      });

    }
  }
};

// 辅助函数 hex2a
function hex2a(hexx) {
  var arr = [];
  for (var i = 0; i < hexx.length; i += 2) {
    arr.push(String.fromCharCode(parseInt(hexx.substr(i, 2), 16)));
  }
  return arr.join('');
}

function currentChangeHandle(val) {
  data.pageIndex = val; // 更新当前页码
  loadDataList(); // 加载数据
}

function searchHandle() {
  proxy.$refs['form'].validate(valid => {
    if (valid) {
      proxy.$refs['form'].clearValidate();

      // 清空空值
      if (dataForm.name === '') {
        dataForm.name = null;
      }

      if (dataForm.tel === '') {
        dataForm.tel = null;
      }

      // 如果当前页为11，则重置为第一页
      if (data.pageIndex === 11) {
        data.pageIndex = 1;
      }

      // 加载数据
      loadDataList();
    } else {
      return false;
    }
  });
}

function checkinHandle() {
  let current = dayjs().format("YYYY.MM-DD");
  if (current < dataForm.date) {
    proxy.$message({
      message: `请将日期改为${current}`,
      type: "warning",
      duration: 1200
    });
  } else {
    checkinDialog.dataForm.name = null;
    checkinDialog.dataForm.sex = null;
    checkinDialog.dataForm.pid = null;
    checkinDialog.dataForm.photo1 = null;
    checkinDialog.dataForm.photo2 = null;
    checkinDialog.showEmpty = true;
    checkinDialog.showVideo = false;
    checkinDialog.showPhoto = false;
    checkinDialog.visible = true;
  }
}

function sizeChangeHandle(val) {
  data.pageSize = val; // 更新页大小
  data.pageIndex = 1; // 每次改变页大小时重置为第一页
  loadDataList(); // 加载数据
}

function hex2x(hex) {
  let str_list = '';
  for (let i = 0; i < hex.length && hex.substr(i, 2) !== '00'; i += 2) {
    const a = hex.charCodeAt(i);
    const b = hex.charCodeAt(i + 1);
    const c = b * 256 + a;
    str_list += String.fromCharCode(c);
  }
  return str_list.toString();
}

function loadDataList() {
  data.loading = true;

  switch (dataForm.statusLabel) {
    case '全部':
      dataForm.status = null;
      break;
    case '未签到':
      dataForm.status = 1;
      break;
    case '已签到':
      dataForm.status = 2;
      break;
    case '已结束':
      dataForm.status = 3;
      break;
    case '已关闭':
      dataForm.status = 4;
      break;
    default:
      console.error('未知状态标签:', dataForm.statusLabel);
  }
  let json = {
    name: dataForm.name,
    tel: dataForm.tel,
    date: dataForm.date,
    status: dataForm.status,
    page: data.pageIndex,
    length: data.pageSize
  };
  proxy.$http('/mis/appointment/searchByPage', 'POST', json, true, function (resp) {
    let page = resp.page;
    let temp = {
      '1': '未签到',
      '2': '已签到',
      '3': '已结束',
      '4': '已关闭'
    };

    // 遍历列表，将状态码转换为对应的文字
    for (let one of page.list) {
      one.status = temp[one.status];
    }

    // 更新数据列表和总数
    data.datalist = page.list;
    data.totalCount = page.totalCount; // 修正错误的赋值
  });
}

// 解析日期函数 parseDateString
function parseDateString(str, deco, zero) {
  let year = str.substr(0, 4);
  let month = str.substr(4, 2);
  let date = str.substr(6, 2);
  if (zero) {
    month = month[0] === '0' ? month[1] : month;
  }
}

function takePhotoHandle() {
  if (checkinDialog.btnText == '拍照') {
    let video = document.querySelector('#video');
    let canvas = document.querySelector('#photo');
    let context = canvas.getContext('2d'); // 获取 2D 绘图上下文

    // 把摄像头当前的取景内容绘制到 canvas 控件中
    context.drawImage(video, 0, 0, 460, 345); // 绘制视频帧到 canvas

    // 显示 canvas 控件，隐藏其他控件
    checkinDialog.showEmpty = false;
    checkinDialog.showVideo = false;
    checkinDialog.showPhoto = true;

    // 显示成功消息
    proxy.$message({
      message: '拍照成功',
      type: "success",
      duration: 1200
    });
    // 更新按钮文字和图标
    checkinDialog.btnText = '拍照';  // 设置按钮文字为 '拍照'
    checkinDialog.btnIcon = 'RefleshRight';  // 设置按钮图标
    checkinDialog.dataForm.photo = canvas.toDataURL("image/jpeg");  // 转换为 JPEG 格式的 base64 编码
  } else {
    // 更新控件显示状态
    checkinDialog.showEmpty = false;  // 隐藏空白控件
    checkinDialog.showVideo = true;   // 显示视频控件
    checkinDialog.showPhoto = false;  // 隐藏照片控件

    checkinDialog.btnText = '拍照';  // 设置按钮文字为 '拍照'
    checkinDialog.btnIcon = 'Camera';  // 设置按钮图标为 'Camera'
  }
}

function dataFormSubmit() {
  let json = {
    pid: checkinDialog.dataForm.pid,
    name: checkinDialog.dataForm.name,
    photo_1: checkinDialog.dataForm.photo_1,  // 修正 photo 1 为 photo_1
    photo_2: checkinDialog.dataForm.photo_2   // 修正 photo 2 为 photo_2
  };

  proxy.$http('/mis/appointment/checkin', 'POST', json, true, function (resp) {
    if (resp.result) {
      ElNotification({
        title: "通知消息",  // 修正了引号
        message: "签到成功", // 修正了引号
        type: 'success',
        duration: 1200
      });
      checkinDialog.showEmpty = true;
      checkinDialog.showVedio = false;
      checkinDialog.showPhoto = false;
      checkinDialog.btnIcon = 'Camera';  // 修正了引号
      checkinDialog.btnText = '拍照';  // 修正了引号

      checkinDialog.dataForm.name = null;
      checkinDialog.dataForm.sex = null;
      checkinDialog.dataForm.pid = null;
      checkinDialog.dataForm.photo_1 = null;  // 修正了变量名
      checkinDialog.dataForm.photo_2 = null;  // 修正了变量名
      loadDataList();
    } else {
      proxy.$message({
        message: "签到失败",
        type: 'error',
        duration: 1200
      })
    }
  });
}


function closeHandle() {
  // 如果存在视频流，停止它
  if (checkinDialog.streamTrack != null) {
    checkinDialog.streamTrack.stop();
  }

  checkinDialog.showEmpty = true;
  checkinDialog.showVideo = false;
  checkinDialog.showPhoto = false;

  checkinDialog.visible = false;

  checkinDialog.btnText = '拍照';
  checkinDialog.btnIcon = 'Camera';
}

function finishHandle() {
  ElMessageBox.prompt(
      "请输入体检单编号，结束该次体检",  // Prompt message
      "提示信息",  // Title
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPlaceholder: "体检编号",
        type: "warning",
        inputPattern: /^[0-9a-zA-Z]{32}$/,  // Regex pattern for a 32-character alphanumeric string
        inputErrorMessage: '体检编号不正确'  // Error message for invalid input
      }
  ).then(({value}) => {
    let json = {
      uuid: value,  // The value of the UUID
      status: 3      // The status value to be updated
    };

// Make the HTTP request
    proxy.$http("/mis/appointment/updateStatusByUuid", "POST", json, true, function (resp) {
      if (resp.result) {
        // If the operation is successful
        proxy.$message({
          message: '操作成功',
          type: 'success',
          duration: 1200,
          onClose: () => {
            loadDataList();  // Reload the data list after success
          }
        });
      } else {
        // If there was an error updating the record
        proxy.$message({
          message: "无法更新记录",
          type: 'error',
          duration: 1200
        });
      }
    });

  }).catch(() => {
  });
}

loadDataList();

</script>
<style scoped lang="less">
@import "customer_check";
</style>
